package com.tokenmaster.aitrade.market.virtual;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.tokenmaster.aitrade.common.system.KLinePoint;
import com.tokenmaster.aitrade.common.ticker.Ticker_Spot;

/**
 * @Description: K线生成,指标计算
 * @author buxinyun
 * @date 2018年6月1日
 *
 */
public class Market_Virtual {

	private static Market_Virtual instance = new Market_Virtual();

	public static Market_Virtual getInstance() {
		return instance;
	}
//    private SystemDB systemDB = SystemDB.getInstance();
//

	private Logger logger = Logger.getLogger(this.getClass());

	private Map<String, List<KLinePoint>> kLinePointsMap = new HashMap<String, List<KLinePoint>>();

	private Ticker_History ticker_History = Ticker_History.getInstance();

	/**
	 * 根据币名称,周期，获取K线
	 * 
	 * @param symbol
	 * @param type
	 * @return
	 * @throws IOException
	 */
	public List<KLinePoint> getKLines(String symbol, String type) throws IOException {

		if (type.equals("5min")) {
			// 从数据库获取最新行情
			Ticker_Spot ticker_Spot = ticker_History.getTicker(symbol);

			SimpleDateFormat sformat = new SimpleDateFormat("MM-dd HH:mm:ss");
			String timestr = sformat.format(Double.valueOf(ticker_Spot.getDate()));

			// logger.info("虚拟行情..." + timestr + " 价格:" +
			// ticker_Spot.getLast());

			// 生成K线
			inputTickerSpot(ticker_Spot);

		}

		return getKLinePoints(symbol, type);
	}

	/**
	 * 输入实时采集数据,现货
	 * 
	 * @param kLinePoint
	 */
	public void inputTickerSpot(Ticker_Spot ticker_Spot) {
		// 生成5分钟K线
		updateKLine(ticker_Spot.getSymbol(), "5min", Long.valueOf(ticker_Spot.getDate()),
				Double.valueOf(ticker_Spot.getLast()), Double.valueOf(ticker_Spot.getVol()));
		// 生成15分钟K线
		updateKLine(ticker_Spot.getSymbol(), "15min", Long.valueOf(ticker_Spot.getDate()),
				Double.valueOf(ticker_Spot.getLast()), Double.valueOf(ticker_Spot.getVol()));
		// 生成1小时K线
		updateKLine(ticker_Spot.getSymbol(), "1hour", Long.valueOf(ticker_Spot.getDate()),
				Double.valueOf(ticker_Spot.getLast()), Double.valueOf(ticker_Spot.getVol()));
		// 生成4小时K线
		updateKLine(ticker_Spot.getSymbol(), "4hour", Long.valueOf(ticker_Spot.getDate()),
				Double.valueOf(ticker_Spot.getLast()), Double.valueOf(ticker_Spot.getVol()));
		// 生成24小时K线
		updateKLine(ticker_Spot.getSymbol(), "1day", Long.valueOf(ticker_Spot.getDate()),
				Double.valueOf(ticker_Spot.getLast()), Double.valueOf(ticker_Spot.getVol()));
	}

	/**
	 * 获取K线临时缓存
	 * 
	 * @param symbol
	 * @param type
	 * @return
	 */
	private List<KLinePoint> getKLinePoints(String symbol, String type) {

		List<KLinePoint> kLinePoints;
		if (kLinePointsMap.containsKey(symbol + "_" + type)) {

			kLinePoints = kLinePointsMap.get(symbol + "_" + type);
		} else {

			kLinePoints = new ArrayList<KLinePoint>();
			kLinePointsMap.put(symbol + "_" + type, kLinePoints);
		}

		return kLinePoints;
	}

	private void updateKLine(String symbol, String type, long currentTime, double currentPrice, double currentVol) {

		List<KLinePoint> destKLinePoints = getKLinePoints(symbol, type);

		long timeInterval = 0;

		if (type.equals("5min")) {
			timeInterval = 5 * 60 * 1000;
		} else if (type.equals("15min")) {
			timeInterval = 15 * 60 * 1000;
		} else if (type.equals("1hour")) {
			timeInterval = 60 * 60 * 1000;
		} else if (type.equals("4hour")) {
			timeInterval = 4 * 60 * 60 * 1000;
		} else if (type.equals("1day")) {
			timeInterval = 24 * 60 * 60 * 1000;
		}

		if (destKLinePoints.size() == 0) {

			// 计算第一个K线
			KLinePoint newKLinePoint = new KLinePoint();
			newKLinePoint.setSymbol(symbol);
			newKLinePoint.setType(type);
			newKLinePoint.setUnixTime((long) (Math.floor(currentTime / timeInterval) * timeInterval));
			newKLinePoint.setHigh(currentPrice);
			newKLinePoint.setLast(currentPrice);
			newKLinePoint.setLow(currentPrice);
			newKLinePoint.setOpen(currentPrice);
			newKLinePoint.setVol(currentVol);
			newKLinePoint.setVolCoin(currentVol);
			destKLinePoints.add(newKLinePoint);

		} else if (currentTime - destKLinePoints.get(destKLinePoints.size() - 1).getUnixTime() > timeInterval) {

			// 最后一条K线保存到数据库
//			systemDB.insertKLine(destKLinePoints.get(destKLinePoints.size() - 1));

			// 生成新的K线
			KLinePoint newKLinePoint = new KLinePoint();
			newKLinePoint.setSymbol(symbol);
			newKLinePoint.setType(type);
			newKLinePoint.setUnixTime((long) (Math.floor(currentTime / timeInterval) * timeInterval));
			newKLinePoint.setHigh(currentPrice);
			newKLinePoint.setLast(currentPrice);
			newKLinePoint.setLow(currentPrice);
			newKLinePoint.setOpen(currentPrice);
			newKLinePoint.setVol(currentVol);
			newKLinePoint.setVolCoin(currentVol);

			destKLinePoints.add(newKLinePoint);

			if (destKLinePoints.size() > 30)
				destKLinePoints.remove(0);

			SimpleDateFormat sformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

			long time = (long) (newKLinePoint.getUnixTime());
			String timestr = sformat.format(time);
			// logger.info("New " + type + " KLinePoint " + timestr + " size=" + destKLinePoints.size());

		} else {
			KLinePoint lastKLinePoint = destKLinePoints.get(destKLinePoints.size() - 1);
			lastKLinePoint.setLast(currentPrice);

			if (currentPrice > lastKLinePoint.getHigh())
				lastKLinePoint.setHigh(currentPrice);
			if (currentPrice < lastKLinePoint.getLast())
				lastKLinePoint.setLow(currentPrice);

		}

	}

}
